#ifndef __SE_LRU_CACHE_HPP__
#define __SE_LRU_CACHE_HPP__

#include "json.hpp"

#include <string>
#include <unordered_map>
#include <list>
#include <vector>

namespace se {

class LRUCache
{
    friend class CacheManager;

    using json = nlohmann::json;
    using Key = std::string;
    using Cache = std::list<std::pair<Key, json>>;
    using HashMap = std::unordered_map<Key, Cache::iterator>;
public:
    LRUCache(size_t size);

    /**
     * @brief 初始化LRUCache时使用，从文件中读取记录
     * @param in fileName 文件名
     */
    void readFromFile(const std::string & fileName);

    /**
     * @brief 用于Cache的持久化，保存Cache内容到文件，以防程序异常退出丢失cache内容
     * @param in fileName 文件名
     */
    void writeToFile(const std::string & fileName);

    /**
     * @brief 把自身_pendingUpdateList转移给目标cache的_pendingUpdateList
     * @param out cache 目标cache
     */
    void movePendingUpdateListTo(LRUCache & cache);

    /**
     * @brief 拷贝LRUCache（不拷贝待更新数据）
     * @param in cache 拷贝的对象
     */
    void copyFrom(const LRUCache & cache);

    /**
     * @brief 查找失败时，将在词典中查找结果插入Cache
     * @param in record 待插入的数据
     */
    void addRecord(const std::pair<Key, json> & record);

    /**
     * @brief 按关键字查找，查找成功时将结果移动到_resultList的头部
     * @parma in key 关键字 
     * @return const json & 查找成功时返回结果值，没找到返回空的json对象
     */
    std::shared_ptr<nlohmann::json> find(const Key & key);

    /**
     * @brief 根据_resultList重新生成_resultMap
     */
    void regenerateResultMap();

    /**
     * @brief 合并_pendingUpdateList到_resultList
     */
    void updateSelf();

    /**
     * @brief 抛弃表尾数据
     */
    void throwOutRecord();

    /**
     * @brief 将记录置为最新数据
     * @param in iter 指向_resultList中待刷新记录的迭代器
     */
    void reNewRecord(Cache::iterator iter); 

    /**
     * @brief 清空缓存
     */
    void clear();

    /**
     * @brief 测试用，打印链表信息
     */
    void print();
private:
    Cache _resultList;
    HashMap _resultMap;
    Cache _pendingUpdateList;
    size_t _size;
};

}  // namespace se

#endif
